<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>doh.robot Validation Test</title>

		<style>
			@import "../../../../util/doh/robot/robot.css";
		</style>

		<!-- required: dojo.js -->
		<script type="text/javascript" src="../../../../dojo/dojo.js"
			djConfig="isDebug: true, parseOnLoad: true"></script>

		<script type="text/javascript">
			dojo.require("dijit.dijit"); // optimize: load dijit layer
			dojo.require("dijit.robotx");

			dojo.addOnLoad(function(){
				doh.robot.initRobot('../test_validate.html');

				// Test initial conditions
				// TODO: convert this to a bunch of doh.is() calls, two per widget (for value and onchange)
				doh.register("setUp", {
					name: "setUp",
					runTest: function(){
						var s = "firstname: Testing Testing\n"
							+ ": not fired yet!\n"
							+ "lastname: TESTING TESTING\n"
							+ ": \n"
							+ "age: \n"
							+ ": not fired yet!\n"
							+ ": \n"
							+ ": \n"
							+ "fav: \n"
							+ "occupation: \n"
							+ ": 3,000\n"
							+ "elevation: 3000\n"
							+ ": not fired yet!\n"
							+ ": $54,775.53\n"
							+ "income1: 54775.53\n"
							+ ": not fired yet!\n"
							+ ": €54,775.53\n"
							+ "income2: 54775.53\n"
							+ ": 54.775,53 €\n"
							+ "income3: 54775.53\n"
							+ "phone: someTestString\n"
							+ "password: \n"
							+ "ticket1651: \n"
							+ "readOnly: cannot type here\n"
							+ "disabled: cannot type here\n";
						doh.is(s, dojo.doc.displayData());
					}
				});

				var _setvaluetest = function(textbox, setVal, focusVal, attrVal, isValid, chgVal, required){
					textbox = dijit.byId(textbox);
					if(required !== undefined){
						textbox.attr('required', required);
					}
					textbox.attr('value', setVal);
					doh.is(focusVal, textbox.focusNode.value, "focusNode.value");
					doh.is(attrVal, textbox.attr('value'), "attr('value')");
					doh.is(typeof attrVal, typeof textbox.attr('value'), "typeof attr('value')");
					doh.is(isValid, textbox.isValid(), "isValid()");
					var d = new doh.Deferred();
					var onChange = dojo.byId('oc3');
					doh.robot.sequence(d.getTestCallback(function(){
						doh.is(chgVal.toString(), onChange.value, "onChange.value");
					}), 500);
					return d;
				};

				doh.register("setvaluetest", [
					{
						name: "valid_max",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', 120, 120, 120, true, 120); }
					},

					{
						name: "out_of_range_max",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', 121, 121, 121, false, 121); }
					},

					{
						name: "valid_min",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', 0, 0, 0, true, 0); }
					},

					{
						name: "out_of_range_min",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', -1, -1, -1, false, -1); }
					},

					{
						name: "invalid",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', 'two', 'two', undefined, false, 'undefined'); }
					},

					{
						name: "null_required",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', null, '', NaN, false, NaN, true); }
					},

					{
						name: "null_notrequired",
						timeout: 1000,
						runTest: function(){ return _setvaluetest('q03', null, '', NaN, true, NaN, false); }
					}
				]);

				doh.register("intermediatechanges", {
					name: "valid",
					textbox: "q01",
					timeout: 60000,
					setUp: function(){
						this.textbox = dijit.byId(this.textbox);
						this.textbox.attr('value', '');
						this.textbox.focusNode.focus();
					},
					runTest: function(){
						var d = new doh.Deferred();
						var onChange = dojo.byId('oc1');
						doh.robot.typeKeys('Testing', 1000, 1400);
						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
							// test that value changed while typing since intermediateChanges = true
							doh.is('Testing', this.textbox.focusNode.value, "focusNode value");
							doh.is('Testing', this.textbox.attr('value'), "attr value");
							doh.is('Testing', onChange.value, "onChange.value");
						})), 1000);
						return d;
					}
				});

				doh.register("allcaps", {
					name: "valid",
					textbox: "q02",
					timeout: 60000,
					setUp: function(){
						this.textbox = dijit.byId(this.textbox);
						this.textbox.attr('value', '');
						this.textbox.focusNode.focus();
					},
					runTest: function(){
						var d = new doh.Deferred();
						doh.robot.typeKeys('Testing', 1000, 1400);
						doh.robot.sequence(function(){
							dojo.byId("q01").focus();
						}, 500);
						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
							doh.is('TESTING', this.textbox.focusNode.value, "focusNode.value");
							doh.is('TESTING', this.textbox.attr('value'), "attr('value')");
						})), 1000);
						return d;
					}
				});

				doh.register("maxlength", [
					{
						name: "3chars",
						textbox: "fav",
						timeout: 60000,
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							doh.robot.typeKeys('100', 1000, 600);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								// test that value changed while typing since intermediateChanges = true
								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
								doh.is(100, this.textbox.attr('value'), "attr('value')");
							})), 1000);
							return d;
						}
					},

					{
						name: "4chars",
						textbox: "fav",
						timeout: 60000,
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							doh.robot.typeKeys('1001', 1000, 800);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								// test that value changed while typing since intermediateChanges = true
								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
								doh.is(100, this.textbox.attr('value'), "attr('value')");
								doh.robot.typeKeys('1', 500, 200);
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('100', this.textbox.focusNode.value, "focusNode.value");
									doh.is(100, this.textbox.attr('value'), "attr('value')");
								})), 500);
							})), 1000);
							return d;
						}
					}
				]);

				doh.register("errorStyle", [
					{
						name: "beforeClick",
						textbox: "q04",
						runTest: function(){
							this.textbox = dijit.byId(this.textbox);
							doh.is('', this.textbox.attr('state'));
							doh.is(false, this.textbox.isValid(), "isValid()");
						}
					},

					{
						name: "afterClick",
						textbox: "q04",
						timeout: 60000,
						runTest: function(){
							var d = new doh.Deferred();
							this.textbox = dijit.byId(this.textbox);
							doh.robot.sequence(dojo.hitch(this, function(){
								this.textbox.focusNode.focus();
							}), 500);
							doh.robot.sequence(dojo.hitch(this, function(){
								dojo.byId("q01").focus();
							}), 1000);	// time for promptMessage to appear on q04 (IE6 takes a while due to iframe)
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('Error', this.textbox.attr('state'));
								doh.is(false, this.textbox.isValid(), "isValid()");
							})), 1000);
							return d;
						}
					},

					{
						name: "valid",
						textbox: "q04",
						timeout: 60000,
						runTest: function(){
							var d = new doh.Deferred();
							this.textbox = dijit.byId(this.textbox);
							this.textbox.focusNode.focus();
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('', this.textbox.attr('state'));
								doh.is(false, this.textbox.isValid(), "isValid()");
								doh.robot.typeKeys('a', 500, 200);
								doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
									doh.is('a', this.textbox.attr('value'), "attr('value')");
									doh.is('', this.textbox.attr('state'));
									doh.is(true, this.textbox.isValid(), "isValid()");
									dojo.byId("q01").focus();
									doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
										doh.is('', this.textbox.attr('state'));
										doh.is(true, this.textbox.isValid(), "isValid()");
									})), 1000);
								})), 500);
							})), 1000);
							return d;
						}
					}
				]);

				doh.register("commaformat", [
					{
						name: "beforeClick",
						textbox: "q05",
						runTest: function(){
							this.textbox = dijit.byId(this.textbox);
							doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
							doh.is('3000', this.textbox.attr('value'), "attr('value')");
							doh.is(true, this.textbox.isValid(), "isValid()");
						}
					},

					{
						name: "click",
						timeout: 60000,
						textbox: "q05",
						runTest: function(){
							var d = new doh.Deferred();
							this.textbox = dijit.byId(this.textbox);
							var onChange = dojo.byId('oc5');
							doh.robot.sequence(dojo.hitch(this, function(){
								this.textbox.focusNode.focus();
							}), 500);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								// comma should disappear on click, value shouldn't change
								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
								doh.is('3000', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('not fired yet!', onChange.value);
							})), 500);
							return d;
						}
					},

					{
						name: "type_valid_nocomma",
						timeout: 60000,
						textbox: "q05",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc5');
							doh.robot.typeKeys('3000', 1000, 800);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('3000', this.textbox.focusNode.value, "focusNode.value");
								doh.is('3000', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('NaN', onChange.value);
								dojo.byId("q01").focus();
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
									doh.is('3000', this.textbox.attr('value'), "attr('value')");
									doh.is(true, this.textbox.isValid(), "isValid()");
									doh.is('3000', onChange.value);
								})), 1000);
							})), 1000);
							return d;
						}
					},

					{
						name: "type_valid_comma",
						timeout: 60000,
						textbox: "q05",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc5');
							doh.robot.typeKeys('3,000', 1000, 1000);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
								doh.is('3000', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('NaN', onChange.value);
								dojo.byId("q01").focus();
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
									doh.is('3000', this.textbox.attr('value'), "attr('value')");
									doh.is(true, this.textbox.isValid(), "isValid()");
									doh.is('3000', onChange.value);
								})), 1000);
							})), 1000);
							return d;
						}
					},

					{
						name: "type_invalid_comma",
						timeout: 60000,
						textbox: "q05",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc5');
							doh.robot.typeKeys('300,0', 1000, 1000);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
								doh.is(undefined, this.textbox.attr('value'), "attr('value')");
								doh.is(false, this.textbox.isValid(), "isValid()");
								doh.is('NaN', onChange.value);
								dojo.byId("q01").focus();
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
									doh.is(undefined, this.textbox.attr('value'), "attr('value')");
									doh.is(false, this.textbox.isValid(), "isValid()");
									doh.is('undefined', onChange.value);
								})), 1000);
							})), 1000);
							return d;
						}
					}
				]);

				doh.register("currencyFormat", [
					{
						name: "beforeClick",
						textbox: "q08",
						runTest: function(){
							this.textbox = dijit.byId(this.textbox);
							doh.is('$54,775.53', this.textbox.focusNode.value, "focusNode.value");
							doh.is('54775.53', this.textbox.attr('value'), "attr('value')");
							doh.is(true, this.textbox.isValid(), "isValid()");
						}
					},

					{
						name: "click",
						timeout: 60000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								// comma should disappear on click, value shouldn't change
								doh.is('54775.53', this.textbox.focusNode.value, "focusNode.value");
								doh.is('54775.53', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('not fired yet!', onChange.value);
							})), 500);
							return d;
						}
					},

					{
						name: "type_valid_number",
						timeout: 60000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('10000.01', 1000, 1600);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('10000.01', this.textbox.focusNode.value, "focusNode.value");
								doh.is('10000.01', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('NaN', onChange.value);
								dojo.byId("q01").focus();
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('$10,000.01', this.textbox.focusNode.value, "focusNode.value");
									doh.is('10000.01', this.textbox.attr('value'), "attr('value')");
									doh.is(true, this.textbox.isValid(), "isValid()");
									doh.is('10000.01', onChange.value);
								})), 1000);
							})), 1000);
							return d;
						}
					},
					{
						name: "type_valid_dollarsign",
						timeout: 60000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('$20000.01', 1000, 1800);
							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
								doh.is('$20000.01', this.textbox.focusNode.value, "focusNode.value");
								doh.is(20000.01, this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
								doh.is('NaN', onChange.value);
								dojo.byId("q01").focus();
								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
									doh.is('$20,000.01', this.textbox.focusNode.value, "focusNode.value");
									doh.is(20000.01, this.textbox.attr('value'), "attr('value')");
									doh.is(true, this.textbox.isValid(), "isValid()");
									doh.is('20000.01', onChange.value);
								})), 1000);
							})), 1000);
							return d;
						}
					},
					{
						name: "missing required decimal",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('123', 1000, 600);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('123', this.textbox.focusNode.value, "focusNode.value");
								doh.is(undefined, this.textbox.attr('value'), "attr('value')");
								doh.f(this.textbox.isValid(), "!isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "too few decimal digits",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('123.0', 1000, 1000);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('123.0', this.textbox.focusNode.value, "focusNode.value");
								doh.is(undefined, this.textbox.attr('value'), "attr('value')");
								doh.f(this.textbox.isValid(), "!isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "too many decimal digits",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('123.000', 1000, 1400);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('123.000', this.textbox.focusNode.value, "focusNode.value");
								doh.is(undefined, this.textbox.attr('value'), "attr('value')");
								doh.f(this.textbox.isValid(), "!isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "negative decimal",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('-123.00', 1000, 1400);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('-123.00', this.textbox.focusNode.value, "focusNode.value");
								doh.is(-123, this.textbox.attr('value'), "attr('value')");
								doh.t(this.textbox.isValid(), "isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "negative currency",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('($123.00)', 1000, 1600);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('($123.00)', this.textbox.focusNode.value, "focusNode.value");
								doh.is(-123, this.textbox.attr('value'), "attr('value')");
								doh.t(this.textbox.isValid(), "isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "convert negative decimal to negative currency",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('-123.45', 1000, 1400);
							doh.robot.keyPress(dojo.keys.TAB, 500, {});
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('($123.45)', this.textbox.focusNode.value, "focusNode.value");
								doh.is(-123.45, this.textbox.attr('value'), "attr('value')");
								doh.t(this.textbox.isValid(), "isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "convert negative negative currency to negative decimal",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('($123.45)', 1000, 1800);
							doh.robot.keyPress(dojo.keys.TAB, 500, {});
							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('-123.45', this.textbox.focusNode.value, "focusNode.value");
								doh.is(-123.45, this.textbox.attr('value'), "attr('value')");
								doh.t(this.textbox.isValid(), "isValid()");
							})), 1000);
							return d;
						}
					},
					{
						name: "exponent not allowed",
						timeout: 6000,
						textbox: "q08",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							var onChange = dojo.byId('oc8');
							doh.robot.typeKeys('1.23e0', 1000, 1200);
							doh.robot.keyPress(dojo.keys.TAB, 500, {});
							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('1.23e0', this.textbox.focusNode.value, "focusNode.value");
								doh.is(undefined, this.textbox.attr('value'), "attr('value')");
								doh.f(this.textbox.isValid(), "!isValid()");
							})), 1000);
							return d;
						}
					}
				]);

				doh.register("euroformat", {
					name: "type_1",
					timeout: 60000,
					textbox: "q08eur",
					setUp: function(){
						this.textbox = dijit.byId(this.textbox);
						this.textbox.attr('value', '');
						this.textbox.focusNode.focus();
					},
					runTest: function(){
						var d = new doh.Deferred();
						doh.robot.typeKeys('1', 1000, 200);
						doh.robot.sequence(dojo.hitch(this, function(){
							dijit.byId('q01').focusNode.focus();
						}), 500);
						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
							doh.is('€1.00', this.textbox.focusNode.value, "focusNode.value");
							doh.is('1', this.textbox.attr('value'), "attr('value')");
							doh.is(true, this.textbox.isValid(), "isValid()");
						})), 1000);
						return d;
					}
				});

				doh.register("regexp", [
					{
						name: "valid",
						timeout: 60000,
						textbox: "q22",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							doh.robot.typeKeys('a', 1000, 200);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('a', this.textbox.focusNode.value, "focusNode.value");
								doh.is('a', this.textbox.attr('value'), "attr('value')");
								doh.is(true, this.textbox.isValid(), "isValid()");
							})), 500);
							return d;
						}
					},

					{
						name: "invalid",
						timeout: 60000,
						textbox: "q22",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							doh.robot.typeKeys('a ', 1000, 400);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('a ', this.textbox.focusNode.value, "focusNode.value");
								doh.is('a ', this.textbox.attr('value'), "attr('value')");
								doh.is(false, this.textbox.isValid(), "isValid()");
							})), 500);
							return d;
						}
					}
				]);

				doh.register("password", {
					name: "type",
					timeout: 60000,
					textbox: "q23",
					setUp: function(){
						this.textbox = dijit.byId(this.textbox);
						this.textbox.attr('value', '');
						this.textbox.focusNode.focus();
					},
					runTest: function(){
						var d = new doh.Deferred();
						doh.robot.typeKeys('abcdef', 1000, 1200);
						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
							doh.is('abcdef', this.textbox.focusNode.value, "focusNode.value");
							doh.is('abcdef', this.textbox.attr('value'), "attr('value')");
						})), 1000);
						return d;
					}
				});

				doh.register("readonly", [
					{
						name: "readonly",
						timeout: 60000,
						textbox: "q24",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							dojo.byId("mname").focus();
						},
						runTest: function(){
							var d = new doh.Deferred();

							// Tab into element (readonly *can* be focused, although disabled can't)
							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift: true});

							// typing on a disabled element should have no effect
							doh.robot.typeKeys('abc', 500, 600);

							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('cannot type here', this.textbox.focusNode.value, "focusNode.value");
								doh.is('cannot type here', this.textbox.attr('value'), "attr('value')");
							})), 1000);
							return d;
						}
					},

					{
						name: "write",
						timeout: 60000,
						textbox: "q24",
						setUp: function(){
							this.textbox = dijit.byId(this.textbox);
							this.textbox.attr('value', '');
							this.textbox.attr('readOnly', false);
							this.textbox.focusNode.focus();
						},
						runTest: function(){
							var d = new doh.Deferred();
							doh.robot.typeKeys('abc', 1000, 600);
							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is('abc', this.textbox.focusNode.value, "focusNode.value");
								doh.is('abc', this.textbox.attr('value'), "attr('value')");
							})), 1000);
							return d;
						}
					}
				]);

				doh.register("disabled", [
					{
						name: "click doesn't focus",
						timeout: 60000,
						setUp: function(){
							var textbox = dijit.byId("q24");
							dojo.byId("mname").focus();
							textbox.attr('disabled', true);
						},
						runTest: function(){
							var d = new doh.Deferred(),
								textbox = dijit.byId("q24");

							//  Clicking shouldn't have any effect since it's disabled
							doh.robot.mouseMoveAt(textbox.focusNode, 500);
							doh.robot.mouseClick({left: true}, 500);

							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.isNot("q24", (dojo.global.dijit._curFocus||{}).id, "didn't focus");
							})), 500);
							return d;
						}
					},

					{
						name: "tab jumps over",
						timeout: 60000,

						setUp: function(){
							var textbox = dijit.byId("q24");
							dojo.byId("mname").focus();
							textbox.attr('disabled', true);
						},
						runTest: function(){
							var d = new doh.Deferred();

							doh.robot.keyPress(dojo.keys.TAB, 500);

							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
								doh.is("removereadonly", dojo.global.dijit._curFocus.id,
										"tabbed past input, to the button after it");
							})), 500);
							return d;
						}
					}
				]);

				doh.run();
			});
		</script>
	</head>
</html>
